
package com.scs.application.modules.base.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.SerialRuleConsts;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.msg.provider.ISceneMsgPushProvider;
import com.scs.application.core.serial.SerialUtils;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.*;
import com.scs.application.enums.CertBusType;
import com.scs.application.modules.base.entity.*;
import com.scs.application.modules.base.mapper.SupplierApplicantMapper;
import com.scs.application.modules.base.request.SupplierApplicantQueryRequest;
import com.scs.application.modules.base.service.*;
import com.scs.application.modules.cert.entity.CertificateRepository;
import com.scs.application.modules.cert.request.CertificateRepositoryQueryRequest;
import com.scs.application.modules.cert.service.CertificateRepositoryService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * SupplierApplicant service 实现
 *
 */
@AllArgsConstructor
@Slf4j
@Service
public class SupplierApplicantServiceImpl extends BaseServiceImpl<SupplierApplicantMapper, SupplierApplicant> implements SupplierApplicantService {
    private final HospitalSupplierService hospitalSupplierService;

    private final SupplierService supplierService;

    private final ISceneMsgPushProvider sceneMsgPushProvider;

    private final HospitalService hospitalService;

    private final CertificateRepositoryService certificateRepositoryService;

    private final ApplicantCertificateRecordService applicantCertificateRecordService;

    @Override
    public List<SupplierApplicant> list(SupplierApplicantQueryRequest request) {
        List<SupplierApplicant> list = this.list(Wrappers.<SupplierApplicant>query()
                .like(StringUtils.isNotBlank(request.getCode()), "code", request.getCode())
                .eq(request.getStatus() != null, "status", request.getStatus())
                .orderByDesc("code")
        );
        return list;
    }

    @Override
    public IPage<SupplierApplicant> page(SupplierApplicantQueryRequest request) {
        request.setSupplierId(UserUtils.getSupplierId());
        return this.baseMapper.page(request.getPage(), request);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SupplierApplicant applicant(SupplierApplicant entity) {

        //申请表中是否存在
        SupplierApplicant applicantServiceOne = this.getOne(Wrappers.<SupplierApplicant>query()
                .eq("hospital_id", entity.getHospitalId())
                .eq("supplier_id", UserUtils.getSupplierId())
                .eq("status", SupplierApplicant.STATUS_SUBMITED)
        );
        if (applicantServiceOne != null) {
            throw new BusinessException("不可重复申请", null);
        }

        //关系表中是否存在
        assertHasExist(entity);

        //供应商，单据号，单据状态
        entity.setSupplierId(UserUtils.getSupplierId())
                .setCode(SerialUtils.generateCode(
                        SerialRuleConsts.BASE_SUPPLIER_APPLICANT_CODE, SerialOwnerUtils.getSupplierOwner(entity.getSupplierId())))
                .setStatus(SupplierApplicant.STATUS_UNSUBMIT);
        boolean b = this.saveOrUpdate(entity);
        return b ? entity : null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submit(String id) {

        SupplierApplicant supplierApplicant = this.getById(id);
        if (supplierApplicant == null) {
            return;
        }

        //状态是否是制单状态
        if (supplierApplicant.getStatus() != SupplierApplicant.STATUS_UNSUBMIT) {
            throw new BusinessException("当前状态不支持提交");
        }
        //关系表中是否存在
        assertHasExist(supplierApplicant);

        //修改状态为提交待审核
        SupplierApplicant tmp = new SupplierApplicant();
        tmp.setSubmitTime(DateUtils.now());
        tmp.setStatus(SupplierApplicant.STATUS_SUBMITED).setId(supplierApplicant.getId());
        this.updateById(tmp);

        // 添加资质信息到资质记录表
        CertificateRepositoryQueryRequest request = new CertificateRepositoryQueryRequest();
        request.setSupplierId(UserUtils.getSupplierId())
                .setBusinessTypeCode(CertBusType.SUPPLIER.getValue())
        ;
        // 获取资质信息
        List<CertificateRepository> crVOList = certificateRepositoryService.pageForAudit(request);
        List<ApplicantCertificateRecord> list = BeanUtils.copyProperties(crVOList, ApplicantCertificateRecord.class);
        list.stream().forEach(o -> o.setApplicantType("SA").setApplicantId(supplierApplicant.getId()));
        // 保存到资质记录表
        applicantCertificateRecordService.saveBatch(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void pass(String id,SupplierApplicant auditSet) {

        SupplierApplicant supplierApplicant = this.getById(id);
        if (supplierApplicant == null) {
            return;
        }

        //状态是否是提交待审核
        if (supplierApplicant.getStatus() != SupplierApplicant.STATUS_SUBMITED) {
            throw new BusinessException("当前状态不支持审核");
        }

        //关系表中是否存在
        assertHasExist(supplierApplicant);

        //修改状态为已审核
        SupplierApplicant applicant = new SupplierApplicant();
        applicant.setStatus(SupplierApplicant.STATUS_PASSED)
                .setId(supplierApplicant.getId());
        if (auditSet != null) {
            if (StringUtils.isNotBlank(auditSet.getAuditor()) ) {
                applicant.setAuditor(auditSet.getAuditor());
            }
            if (auditSet.getGmtAudited() != null ) {
                applicant.setGmtAudited(auditSet.getGmtAudited());
            }
        } else{
            applicant.setAuditor(UserUtils.getHospital().getName())
                    .setGmtAudited(new Date());
        }
        this.updateById(applicant);


        //添加信息到关系表
        HospitalSupplier hospitalSupplier = new HospitalSupplier();
        BeanUtils.copyProperties(supplierApplicant, hospitalSupplier);
        hospitalSupplier.setInactive(HospitalSupplier.ENABLE);
        hospitalSupplierService.save(hospitalSupplier);

//        //发送审核消息给供应商
//        Supplier supplier = supplierService.getById(supplierApplicant.getSupplierId());
//        Hospital hospital = hospitalService.getById(supplierApplicant.getHospitalId());

        /*HashMap<String, Object> params = Maps.newHashMap();
        params.put("hospital_name", hospital.getName());
        params.put("send_date", DateUtils.format(new Date(), "yyyy-MM-dd"));*/

//        SceneMessage message = new SceneMessage();
//        message.setSceneCode(MsgConsts.SCENE_SUPPLIER_APP_SUCCESS).setReceiver(supplier.getLoginKey())
//                .setReceiverType(ReceiverType.USER);
//        message.addParam("first", "你好，你的供方申请已通过", MessageType.WECHAT)
//                .addParam("keyword1", hospital.getName(), MessageType.WECHAT)
//                .addParam("keyword2", DateUtils.format(new Date(), "yyyy-MM-dd"), MessageType.WECHAT)
//                .addParam("keyword3", "审核通过", MessageType.WECHAT)
//                .addParam("remark", "申请单号：" + supplierApplicant.getCode(), MessageType.WECHAT);
//
//        sceneMsgPushProvider.push(message);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(String id, String auditedRemark) {

        SupplierApplicant supplierApplicant = this.getById(id);

        if (supplierApplicant == null) {
            return;
        }

        //状态是否是提交待审核
        if (supplierApplicant.getStatus() != SupplierApplicant.STATUS_SUBMITED) {
            throw new BusinessException("当前状态不支持取消", null);
        }

        //修改状态为已取消
        SupplierApplicant applicant = new SupplierApplicant();
        applicant.setStatus(SupplierApplicant.STATUS_CANCELED)
                .setGmtAudited(new Date())
                .setAuditor(UserUtils.getHospital().getName())
                .setAuditedRemark(auditedRemark)
                .setId(supplierApplicant.getId());
        this.updateById(applicant);

        applicantCertificateRecordService.remove(Wrappers.<ApplicantCertificateRecord>query()
                .eq(StringUtils.isNotBlank(id), "applicant_id", id));
    }

    @Override
    public IPage<SupplierApplicant> pageAudit(SupplierApplicantQueryRequest request) {
        request.setHospitalId(UserUtils.getHospitalId());
        return this.baseMapper.pageAudit(request.getPage(), request);
    }


    /**
     * 关系表中查找并返回
     *
     * @param entity
     * @return
     */
    public void assertHasExist(SupplierApplicant entity) {
        String supplierId;
        if (StringUtils.isNotBlank(entity.getSupplierId())) {
            supplierId = entity.getSupplierId();
        } else {
            supplierId = entity.getSupplierId();
        }

        //关系表中是否存在
        HospitalSupplier one = hospitalSupplierService.getOne(
                Wrappers.<HospitalSupplier>query()
                        .eq("hospital_id", entity.getHospitalId())
                        .eq("supplier_id", supplierId)
        );
        if (one != null) {
            throw new BusinessException("关系已存在", null);
        }
    }

    private void fillData(SupplierApplicant entity) {
        Hospital hospital =  hospitalService.getById(entity.getHospitalId());
        BusinessException.throwErrorIf(hospital == null,"医院不存在,请联系管理员");

        Supplier supplier =  supplierService.getById(entity.getSupplierId());
        BusinessException.throwErrorIf(supplier == null,"供应商不存在,请联系管理员");
        entity.setSupplierName(supplier.getName()).setHospitalName(hospital.getName());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(SupplierApplicant entity) {
        //关系表中是否存在
        assertHasExist(entity);
        if (entity.isNewRecord()) {
            entity.setCode(SerialUtils.generateCode(
                            SerialRuleConsts.BASE_SUPPLIER_APPLICANT_CODE, SerialOwnerUtils.getSupplierOwner(entity.getSupplierId())))
                    .setStatus(SupplierApplicant.STATUS_UNSUBMIT);
        }
        super.saveOrUpdate(entity);
        fillData(entity);
        return true;
    }

    @Override
    public SupplierApplicant getById(Serializable id) {
        SupplierApplicant entity = super.getById(id);
        fillData(entity);
        return entity;
    }

    @Override
    public void saveBatchWithPass(List<SupplierApplicant> applicantList) {
        this.saveBatch(applicantList);

        List<HospitalSupplier> hospitalSupplierList = new ArrayList<>();
        HospitalSupplier hospitalSupplier;
        for (SupplierApplicant applicant : applicantList) {
            hospitalSupplier = new HospitalSupplier();
            BeanUtils.copyProperties(applicant, hospitalSupplier);
            hospitalSupplier.setInactive(HospitalSupplier.ENABLE);
            hospitalSupplierList.add(hospitalSupplier);
        }
        hospitalSupplierService.saveBatch(hospitalSupplierList);
    }
}
